iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
自我挑戰組

被MongoDB用Aggregate暴打的後端小菜雞日記系列 第 11

被MongoDB用Aggregate暴打的後端小菜雞日記-day11- 用$sample、$rand隨機取得資料

  • 分享至 

  • xImage
  •  

前面十天介紹不少aggregate用法,以簡單的小型專案來說,這些操作符基本上都夠用,熟練之後如果有接到其他特別的需求,其實自己再去MongoDB官網上找其他的操作符使用,不會有太大的問題,官網很貼心附上語法的範例,以及處理前後的資料。

因此接下來介紹的操作符,都比較進階或是比較冷門一點,大家可以參考看看,搞不好在未來的某一天會用到。

首先介紹$sample,它可以讓我們從眾多的資料當中,隨機選出幾筆資料出來,這個很適合用在當你資料庫的資料很多,即使經過$macth篩選過讓資料筆數減少很多,但可能資料還是有1000筆以上,如果通通從資料庫拉回到server進行隨機選取,勢必會拖慢效能。

例如:我們現在有三萬筆使用者的消費資料,我們要從中選單筆消費超過3000元的消費,進行抽獎選出1名幸運得主。

{ id: 1, customer_id: 2, consume: 1200, date: "2022-01-08T06:12:03Z" },
{ id: 2, customer_id: 1, consume: 4300, date: "2022-03-18T06:12:03Z" },
{ id: 3, customer_id: 12, consume: 200, date: "2022-05-01T06:12:03Z" },
{ id: 4, customer_id: 35, consume: 8200, date: "2022-07-15T06:12:03Z"},
.
.
.
以下省略

我們可以使用以下指令

order.aggregate([
  { $match: { consume: { $gte: 3000 } } },
  { $sample: { size: 1 } }
]);

// 最後回傳資料 (每一次跑都會不一樣)
{ id: 1234, customer_id: 305, consume: 4500, date: "2022-02-25T06:12:03Z" }

其中$sample主要是透過size後面的數字來決定要選幾筆資料,如果要抽出的資料筆數,超過原本資料有的筆數,那只會回傳所有的資料。


另一個要介紹的操作符是$rand,它的作用和JavaScript的Math.random()類似,會隨機產生一個0到1之間的小數,如果想要隨機選取特定比例的資料出來,可以使用這個操作符。

例如:我們現在有跟上面一樣的使用者的消費資料,我們要從中選30%的資料出來進行分析,那麼可以使用以下指令。

order.aggregate([
  { $match: 
    { $expr: { $lt: [0.3, { $rand: {} }] } } 
  }
]);

上面指令背後運行的邏輯是,在搜尋每一筆資料的時候,會使用$rand隨機產生一個0~1的小數,判斷是否比0.3還要小,如果是則

本篇文章同步放在我的部落格,大家有空可以進來逛逛


上一篇
被MongoDB用Aggregate暴打的後端小菜雞日記-day10-$lookup將兩個collection的資料合併(下)
下一篇
被MongoDB用Aggregate暴打的後端小菜雞日記-day12-$cond、$switch條件判斷
系列文
被MongoDB用Aggregate暴打的後端小菜雞日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言